﻿// ===================================
// Author : Micro.SanVey
// Eamil  : sanvey.china@gmail.com
// ===================================

namespace U.Help.Net
{
    #region 引用
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    #endregion

    /// <summary>
    /// Http请求帮助类
    /// </summary>
    public class HttpEx
    {
        #region ------------------ 属性字段 ------------------

        //请求地址
        private readonly string _url;
        //请求数据
        private readonly byte[] _Data;
        //Http头
        private Dictionary<String, String> _headers;
        //Http请求类型
        private readonly Method _methon;

        #endregion

        #region ------------------ 构造函数 ------------------

        /// <summary>
        /// Http请求
        /// </summary>
        /// <param name="url">Http请求地址</param>
        /// <param name="methon">Http请求类型</param>
        /// <param name="data">Http请求数据</param>
        public HttpEx(string url, Method methon, byte[] data)
        {
            this._url = url;
            this._methon = methon;
            this._Data = data;
        }

        #endregion

        #region ------------------ 事件委托 ------------------

        /// <summary>
        /// Http请求成功事件
        /// </summary>
        public event EventHandler<HttpSuccessEventArgs> OnSuccess;
        /// <summary>
        /// Http请求失败事件
        /// </summary>
        public event EventHandler<HttpFailEventArgs> OnFailed;

        #endregion

        #region ------------------ 公开方法 ------------------

        /// <summary>
        /// 异步执行Http请求
        /// </summary>
        public void Run()
        {
            try
            {
                var request = WebRequest.CreateHttp(this._url) as HttpWebRequest;
                request.Method = _methon.ToString();
                var dic = _headers.GetEnumerator();
                while (dic.MoveNext()) request.Headers[dic.Current.Key] = dic.Current.Value;

                request.BeginGetRequestStream(GetRequestStream, request);
            }
            catch (Exception ex)
            {
                if (OnFailed != null)
                {
                    OnFailed(null, new HttpFailEventArgs { ErrMsg = ex.Message });
                }
            }
        }

        /// <summary>
        /// 设置Http标签头
        /// </summary>
        /// <param name="headers">键值对</param>
        public void SetHeader(Dictionary<String, String> headers)
        {
            this._headers = headers;
        }

        #endregion

        #region ------------------ 私有方法 ------------------


        private void GetRequestStream(IAsyncResult async)
        {
            var request = (WebRequest)async.AsyncState;

            if (this._Data != null)
            {
                var stream = request.EndGetRequestStream(async);
                stream.Write(_Data, 0, _Data.Length);
                stream.Flush();
                stream.Close();
            }

            request.BeginGetResponse(ResponseCallback, request);
        }

        private void ResponseCallback(IAsyncResult async)
        {
            var request = (HttpWebRequest)async.AsyncState;
            WebResponse response = null;
            try
            {
                response = request.EndGetResponse(async);
                using (var stream = response.GetResponseStream())
                {
                    var len = response.ContentLength;
                    byte[] buff = new byte[len];
                    stream.Read(buff, 0, (int)len);

                    if (OnSuccess != null)
                        OnSuccess(null, new HttpSuccessEventArgs { ReciveByte = buff });

                }
            }
            catch (Exception ex)
            {
                if (OnFailed != null)
                    OnFailed(null, new HttpFailEventArgs { ErrMsg = ex.Message });
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
        }

        #endregion
    }
    
    /// <summary>
    /// Http请求成功数据
    /// </summary>
    public class HttpSuccessEventArgs : EventArgs
    {
        /// <summary>
        /// 接收数组
        /// </summary>
        public byte[] ReciveByte;
    }

    /// <summary>
    /// Http请求失败数据
    /// </summary>
    public class HttpFailEventArgs : EventArgs
    {
        /// <summary>
        /// 错误信息
        /// </summary>
        public string ErrMsg;
    }

    /// <summary>
    /// 数据类型
    /// </summary>
    public enum DataFormat
    {
        Json,
        Xml
    }

    /// <summary>
    /// HTTP请求方法
    /// </summary>
    public enum Method
    {
        GET,
        POST,
        PUT,
        DELETE,
        HEAD,
        OPTIONS,
        PATCH
    }
}